package produce_and_consumer;

import java.util.*;

/**
 * @description:
 * @author: walt-zhong
 * @createDate: 2021/9/14
 */
public class ProducerConsumer {
    private static final int CAPACITY = 5;


    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<Integer>();
        Thread p1 = new Producer(queue,CAPACITY,"P1");
        Thread p2 = new Producer(queue,CAPACITY,"P2");

        Thread c1 = new Consumer(queue,"C1",CAPACITY);
        Thread c2 = new Consumer(queue,"C2",CAPACITY);
        Thread c3 = new Consumer(queue,"C3",CAPACITY);

        p1.start();
        p2.start();

        c1.start();
        c2.start();
        c3.start();


    }

    //Producer

    public static class Producer extends Thread{
        private final Queue<Integer> queue;
        private int maxSize;
        private String name;
        int elem =0;

        public Producer(Queue<Integer> queue,int maxSize,String name){
            super(name);
            this.name = name;
            this.queue = queue;
            this.maxSize = maxSize;
        }

        @Override
        public void run() {
            while (true){
                //给队列加锁，保证线程安全
                synchronized (queue){
                    //队列满，等待消费者消费
                    while (queue.size() == maxSize){
                        System.out.println("Queue is full Producer ["+name + "] thread wait for Consumer to consume");
                        try {
                            queue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

             //队列没有达到最大容量时，生产者被唤醒进行操作
                    System.out.println("Producer [" + name + "] produce value" + elem);
                    queue.offer(elem++);
                    queue.notifyAll();

                    try {
                        Thread.sleep(new Random().nextInt(1000));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    }

    public static class Consumer extends Thread{
        private final Queue<Integer> queue;
        private String name;
        private int maxSize;

        public Consumer(Queue<Integer> queue,String name,int maxSize){
            super(name);
            this.queue = queue;
            this.name = name;
            this.maxSize = maxSize;
        }
        @Override
        public void run() {
            while (true){
              synchronized (queue){
                  while (queue.isEmpty()){
                      System.out.println("Queue is empty,Consumer [" + name + "] thread wait for Producer to product");
                      try {
                          queue.wait();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }

                  //队列中有元素则消费
                  int x = queue.poll();
                  System.out.println("[" + name + "] Consumer consume value: " + x);
                  queue.notifyAll();

                  try {
                      Thread.sleep(new Random().nextInt(1000));
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  //List<Number> l = new ArrayList<Integer>();
              }
            }

        }
    }

}
